package org.rsbot.loader.script;

import B;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import org.rsbot.loader.asm.ClassAdapter;
import org.rsbot.loader.asm.ClassReader;
import org.rsbot.loader.asm.ClassVisitor;
import org.rsbot.loader.asm.ClassWriter;
import org.rsbot.loader.script.adapter.AddFieldAdapter;
import org.rsbot.loader.script.adapter.AddFieldAdapter.Field;
import org.rsbot.loader.script.adapter.AddGetterAdapter;
import org.rsbot.loader.script.adapter.AddGetterAdapter.Field;
import org.rsbot.loader.script.adapter.AddInterfaceAdapter;
import org.rsbot.loader.script.adapter.AddMethodAdapter;
import org.rsbot.loader.script.adapter.AddMethodAdapter.Method;
import org.rsbot.loader.script.adapter.InsertCodeAdapter;
import org.rsbot.loader.script.adapter.OverrideJavaClassAdapter;
import org.rsbot.loader.script.adapter.SetSignatureAdapter;
import org.rsbot.loader.script.adapter.SetSignatureAdapter.Signature;
import org.rsbot.loader.script.adapter.SetSuperAdapter;

public class ModScript
{
  public static final int MAGIC = 16441261;
  private String name;
  private int version;
  private Map<String, String> attributes;
  private Map<String, ClassAdapter> adapters;
  private Map<String, ClassWriter> writers;

  public ModScript(byte[] paramArrayOfByte)
    throws ParseException
  {
    load(new Buffer(paramArrayOfByte));
  }

  public String getName() {
    return this.name;
  }

  public int getVersion() {
    return this.version;
  }

  public String getAttribute(String paramString) {
    return (String)this.attributes.get(paramString);
  }

  public byte[] process(String paramString, byte[] paramArrayOfByte) {
    ClassAdapter localClassAdapter = (ClassAdapter)this.adapters.get(paramString);
    if (localClassAdapter != null) {
      ClassReader localClassReader = new ClassReader(paramArrayOfByte);
      localClassReader.accept(localClassAdapter, 4);
      return ((ClassWriter)this.writers.get(paramString)).toByteArray();
    }
    return paramArrayOfByte;
  }

  public byte[] process(String paramString, InputStream paramInputStream) throws IOException {
    ClassAdapter localClassAdapter = (ClassAdapter)this.adapters.get(paramString);
    if (localClassAdapter != null) {
      localObject = new ClassReader(paramInputStream);
      ((ClassReader)localObject).accept(localClassAdapter, 4);
      return ((ClassWriter)this.writers.get(paramString)).toByteArray();
    }
    Object localObject = new ByteArrayOutputStream();
    byte[] arrayOfByte = new byte[4096];
    int i;
    while ((i = paramInputStream.read(arrayOfByte)) != -1) {
      ((ByteArrayOutputStream)localObject).write(arrayOfByte, 0, i);
    }
    return (B)((ByteArrayOutputStream)localObject).toByteArray();
  }

  private void load(Buffer paramBuffer) throws ParseException {
    if (paramBuffer.g4() != 16441261) {
      throw new ParseException("Bad magic!");
    }
    this.attributes = new HashMap();
    this.adapters = new HashMap();
    this.writers = new HashMap();
    this.name = paramBuffer.gstr();
    this.version = paramBuffer.g2();
    int i = paramBuffer.g2();
    while (i-- > 0) {
      int j = paramBuffer.g1();
      String str1;
      if (j == 1) {
        str1 = paramBuffer.gstr();
        String str2 = paramBuffer.gstr();
        this.attributes.put(str1, new StringBuilder(str2).reverse().toString());
      }
      else
      {
        int k;
        int n;
        Object localObject1;
        Object localObject2;
        if ((j == 2) || (j == 3)) {
          str1 = paramBuffer.gstr();
          k = paramBuffer.g2(); n = 0;
          localObject1 = new AddGetterAdapter.Field[k];
          while (n < k) {
            localObject2 = new AddGetterAdapter.Field();
            ((AddGetterAdapter.Field)localObject2).getter_access = paramBuffer.g4();
            ((AddGetterAdapter.Field)localObject2).getter_name = paramBuffer.gstr();
            ((AddGetterAdapter.Field)localObject2).getter_desc = paramBuffer.gstr();
            ((AddGetterAdapter.Field)localObject2).owner = paramBuffer.gstr();
            ((AddGetterAdapter.Field)localObject2).name = paramBuffer.gstr();
            ((AddGetterAdapter.Field)localObject2).desc = paramBuffer.gstr();

            localObject1[(n++)] = localObject2;
          }
          this.adapters.put(str1, new AddGetterAdapter(delegate(str1), j == 3, localObject1));
        } else if (j == 4) {
          str1 = paramBuffer.gstr();
          k = paramBuffer.g2(); n = 0;
          localObject1 = new AddFieldAdapter.Field[k];
          while (n < k) {
            localObject2 = new AddFieldAdapter.Field();
            ((AddFieldAdapter.Field)localObject2).access = paramBuffer.g4();
            ((AddFieldAdapter.Field)localObject2).name = paramBuffer.gstr();
            ((AddFieldAdapter.Field)localObject2).desc = paramBuffer.gstr();
            localObject1[(n++)] = localObject2;
          }
          this.adapters.put(str1, new AddFieldAdapter(delegate(str1), localObject1));
        } else if (j == 5) {
          str1 = paramBuffer.gstr();
          k = paramBuffer.g2(); n = 0;
          localObject1 = new AddMethodAdapter.Method[k];
          while (n < k) {
            localObject2 = new AddMethodAdapter.Method();
            ((AddMethodAdapter.Method)localObject2).access = paramBuffer.g4();
            ((AddMethodAdapter.Method)localObject2).name = paramBuffer.gstr();
            ((AddMethodAdapter.Method)localObject2).desc = paramBuffer.gstr();
            byte[] arrayOfByte1 = new byte[paramBuffer.g4()];
            paramBuffer.gdata(arrayOfByte1, arrayOfByte1.length, 0);
            ((AddMethodAdapter.Method)localObject2).code = arrayOfByte1;
            ((AddMethodAdapter.Method)localObject2).max_locals = paramBuffer.g1();
            ((AddMethodAdapter.Method)localObject2).max_stack = paramBuffer.g1();
            localObject1[(n++)] = localObject2;
          }
          this.adapters.put(str1, new AddMethodAdapter(delegate(str1), localObject1));
        }
        else
        {
          String str3;
          if (j == 6) {
            str1 = paramBuffer.gstr();
            str3 = paramBuffer.gstr();
            this.adapters.put(str1, new AddInterfaceAdapter(delegate(str1), str3));
          } else if (j == 7) {
            str1 = paramBuffer.gstr();
            str3 = paramBuffer.gstr();
            this.adapters.put(str1, new SetSuperAdapter(delegate(str1), str3));
          } else if (j == 8) {
            str1 = paramBuffer.gstr();
            int m = paramBuffer.g2(); n = 0;
            localObject1 = new SetSignatureAdapter.Signature[m];
            while (n < m) {
              localObject2 = new SetSignatureAdapter.Signature();
              ((SetSignatureAdapter.Signature)localObject2).name = paramBuffer.gstr();
              ((SetSignatureAdapter.Signature)localObject2).desc = paramBuffer.gstr();
              ((SetSignatureAdapter.Signature)localObject2).new_access = paramBuffer.g4();
              ((SetSignatureAdapter.Signature)localObject2).new_name = paramBuffer.gstr();
              ((SetSignatureAdapter.Signature)localObject2).new_desc = paramBuffer.gstr();
              localObject1[(n++)] = localObject2;
            }
            this.adapters.put(str1, new SetSignatureAdapter(delegate(str1), localObject1));
          }
          else
          {
            String str4;
            if (j == 9) {
              str1 = paramBuffer.gstr();
              str4 = paramBuffer.gstr();
              String str5 = paramBuffer.gstr();
              int i2 = paramBuffer.g1();
              localObject2 = new HashMap();
              while (i2-- > 0) {
                int i3 = paramBuffer.g2();
                byte[] arrayOfByte2 = new byte[paramBuffer.g4()];
                paramBuffer.gdata(arrayOfByte2, arrayOfByte2.length, 0);
                ((Map)localObject2).put(Integer.valueOf(i3), arrayOfByte2);
              }
              this.adapters.put(str1, new InsertCodeAdapter(delegate(str1), str4, str5, (Map)localObject2, paramBuffer.g1(), paramBuffer.g1()));
            }
            else if (j == 10) {
              str1 = paramBuffer.gstr();
              str4 = paramBuffer.gstr();

              int i1 = paramBuffer.g1();
              while (i1-- > 0) {
                String str6 = paramBuffer.gstr();
                this.adapters.put(str6, new OverrideJavaClassAdapter(delegate(str6), str1, str4));
              }
            }
          }
        }
      }
    }
  }

  private ClassVisitor delegate(String paramString) {
    ClassAdapter localClassAdapter = (ClassAdapter)this.adapters.get(paramString);
    if (localClassAdapter == null) {
      ClassWriter localClassWriter = new ClassWriter(0);
      this.writers.put(paramString, localClassWriter);
      return localClassWriter;
    }
    return localClassAdapter;
  }

  public static abstract interface Opcodes
  {
    public static final int ATTRIBUTE = 1;
    public static final int GET_STATIC = 2;
    public static final int GET_FIELD = 3;
    public static final int ADD_FIELD = 4;
    public static final int ADD_METHOD = 5;
    public static final int ADD_INTERFACE = 6;
    public static final int SET_SUPER = 7;
    public static final int SET_SIGNATURE = 8;
    public static final int INSERT_CODE = 9;
    public static final int OVERRIDE_JAVA_CLASS = 10;
  }
}